home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SNNSV32.ZIP / SNNSv3.2 / tools / sources / analyze.c next >
Encoding:
C/C++ Source or Header  |  1994-04-25  |  19.6 KB  |  599 lines

  1. /*****************************************************************************
  2.   FILE           : analyze.c
  3.   SHORTNAME      : analyze.c
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : Network Analyzation Tool
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Stefan Broeckel, Tobias Soyez 
  10.   DATE           : 30.07.92
  11.  
  12.   CHANGED BY     : Michael Vogt
  13.   IDENTIFICATION : @(#)analyze.c    1.3 4/6/94
  14.   SCCS VERSION   : 1.3
  15.   LAST CHANGE    : 4/6/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20.  
  21.  
  22. /*****************************************************************************/
  23. /* included headers                                                          */
  24. /*****************************************************************************/
  25.  
  26. #include <stdio.h>
  27.  
  28.  
  29. /*****************************************************************************/
  30. /* constants                                                                 */
  31. /*****************************************************************************/
  32.  
  33. #define  WRONG   1
  34. #define  RIGHT   2
  35. #define  UNKNOWN 4
  36.  
  37. #define  ON  1
  38. #define  OFF 2
  39.  
  40. #define  R402040  1
  41. #define  WTA      2
  42.  
  43.  
  44. /*****************************************************************************/
  45. /* type definitions                                                          */
  46. /*****************************************************************************/
  47.  
  48. typedef struct 
  49. {
  50.   int  no_of_patterns           ;
  51.   int  no_of_input_units        ;
  52.   int  no_of_output_units       ;
  53.   int  startpattern             ;
  54.   int  endpattern               ;
  55.   int  input_pattern_included   ;
  56.   int  teaching_output_included ;
  57.   int  sub_pattern_present      ;
  58. } FileHeaderInfo ;
  59.  
  60.  
  61. /*****************************************************************************/
  62. /* global variables                                                          */
  63. /*****************************************************************************/
  64.  
  65. FILE  *in_file  ;
  66. FILE  *out_file ;
  67.  
  68.  
  69.  
  70. /*****************************************************************************/
  71. /* function Error                                                            */
  72. /*****************************************************************************/
  73.  
  74. float Error (output, teaching_output, no_of_units)
  75.  
  76.   float  *output          ;
  77.   float  *teaching_output ;
  78.   int    no_of_units      ;
  79.  
  80.   {   
  81.     int    i ;
  82.     float  e, diff ;
  83.  
  84.     e = 0.0 ;
  85.     for (i = 0 ; i < no_of_units ; i++)
  86.     { diff = teaching_output[i] - output[i]  ;
  87.       e    = e + diff * diff                 ;
  88.     }
  89.     
  90.     return e;
  91.   }
  92.  
  93.  
  94.  
  95. /*****************************************************************************/
  96. /* The function F_402040 returns :                                           */
  97. /*                                                                           */
  98. /*    RIGHT   : the output of exactly one unit is >= high               and  */
  99. /*              this unit has the greatest teaching output              and  */
  100. /*              the output of all the other units is <= low                  */
  101. /*                                                                           */
  102. /*    WRONG   : the output of exactly one unit is >= high               and  */
  103. /*              this unit has NOT the greatest teaching output          and  */
  104. /*              the output of all the other units is <= low                  */
  105. /*                                                                           */
  106. /*    UNKNOWN : in any other case                                            */
  107. /*                                                                           */
  108. /* high, low  : parameters of F_402040                                       */
  109. /*              default values: low = 0.4, high = 0.6                        */
  110. /*****************************************************************************/
  111.  
  112. int F_402040 (output, teaching_output, no_of_units, high, low)
  113.  
  114.   float  *output          ;
  115.   float  *teaching_output ;
  116.   int    no_of_units      ;
  117.   float  high             ;
  118.   float  low              ;
  119.  
  120.  
  121.   {
  122.     int    o_pos, t_pos ;
  123.     int    on, off, i   ;
  124.     float  t_max        ;
  125.  
  126.     on    = 0 ;
  127.     off   = 0 ;
  128.     o_pos = 0 ;
  129.     t_pos = 0 ;
  130.     t_max = teaching_output[t_pos] ;
  131.  
  132.     for (i = 0 ; i < no_of_units ; i++)
  133.     {
  134.       if      (output[i] >= high) { on++  ; o_pos = i ; } 
  135.       else if (output[i] <= low)    off++ ;
  136.     
  137.       if (teaching_output[i] > t_max)
  138.       {  t_max = teaching_output[i] ;
  139.          t_pos = i ; 
  140.       } 
  141.     }
  142.  
  143.     if ((on + off == no_of_units) && (on == 1))
  144.     {  if (o_pos == t_pos)
  145.             return (RIGHT) ;
  146.        else return (WRONG) ;
  147.     }
  148.     else return (UNKNOWN) ;
  149.   }
  150.  
  151.  
  152.  
  153. /*****************************************************************************/
  154. /* The function F_WTA returns :                                              */
  155. /*                                                                           */
  156. /*    RIGHT   :  there is exactly one unit j with maximal output a       and */
  157. /*               a > high                                                and */
  158. /*               the output of all the other units is < a - low          and */
  159. /*               the unit j has the greatest teaching output                 */
  160. /*                                                                           */
  161. /*    WRONG   :  there is exactly one unit j with maximal output a       and */
  162. /*               a > high                                                and */
  163. /*               the output of all the other units is < a - low          and */
  164. /*               the unit j has NOT the greatest teaching output             */
  165. /*                                                                           */
  166. /*    UNKNOWN :  in any other case                                           */
  167. /*                                                                           */
  168. /* high, low  : parameters of F_WTA                                          */
  169. /*              default values: low = 0.0, high = 0.0                        */
  170. /*****************************************************************************/
  171.  
  172. int F_WTA (output, teaching_output, no_of_units, high, low)
  173.  
  174.   float  *output          ;
  175.   float  *teaching_output ;
  176.   int    no_of_units      ;
  177.   float  high             ;
  178.   float  low              ;
  179.  
  180.  
  181.   {
  182.     int    i, o_pos, t_pos, no_of_max ;
  183.     float  min, max, max2 , t_max     ;
  184.  
  185.  
  186.     o_pos     = 0                      ;
  187.     t_pos     = 0                      ;
  188.     t_max     = teaching_output[t_pos] ;
  189.     max       = output[o_pos]          ;
  190.     min       = max                    ;
  191.     no_of_max = 1                      ;
  192.  
  193.     for (i = 1 ; i < no_of_units ; i++)
  194.     { if (output[i] > max)
  195.       {  max       = output[i] ; 
  196.          o_pos     = i         ;
  197.          no_of_max = 1         ;
  198.       }
  199.       else if (output[i] == max) no_of_max++     ;
  200.       else if (output[i] <  min) min = output[i] ;
  201.  
  202.       if (teaching_output[i] > t_max)
  203.       {  t_max = teaching_output[i] ;
  204.          t_pos = i ; 
  205.       } 
  206.     }
  207.    
  208.     max2 = min  ;
  209.     for (i = 1 ; i < no_of_units ; i++) 
  210.       if ((output[i] > max2) && (output[i] < max)) max2 = output[i] ;
  211.  
  212.     if ((no_of_max == 1) && (output[o_pos] > high) && (max2  < max - low))
  213.     {  if (o_pos == t_pos)
  214.             return (RIGHT) ; 
  215.        else return (WRONG) ;
  216.     }
  217.     else return (UNKNOWN) ;
  218.   }
  219.  
  220.  
  221.  
  222. /*****************************************************************************/
  223. /*  function get_options                                                     */
  224. /*****************************************************************************/
  225.  
  226. int get_options (argc, argv, function, sel_cond, output_text, high, low, 
  227.          statistics)
  228.  
  229.   int    argc         ;
  230.   char   *argv[]      ;
  231.   int    *function    ;
  232.   int    *sel_cond    ;
  233.   int    *output_text ;
  234.   float  *high        ;
  235.   float  *low         ;
  236.   int    *statistics  ;
  237.  
  238.   {
  239.     int          c       ;
  240.     extern char  *optarg ;
  241.     int          error   ;
  242.     int          hl_flag ;
  243.  
  244.     *function    = R402040       ;
  245.     *sel_cond    = 0             ;
  246.     *output_text = OFF           ;
  247.     *statistics  = OFF           ;
  248.     in_file      = (FILE *) NULL ;
  249.     out_file     = (FILE *) NULL ;
  250.     hl_flag      = 0             ;
  251.  
  252.     error = 0 ;
  253.    
  254.     while ((c = getopt (argc, argv, "awruve:i:o:h:l:s")) != -1)
  255.       switch (c)
  256.       {  
  257.         case 'l' :
  258.           sscanf (optarg, "%f", low) ;
  259.           hl_flag = hl_flag | 1 ;
  260.           break ;
  261.         case 'h' :
  262.           sscanf (optarg, "%f", high) ;
  263.           hl_flag = hl_flag | 2 ;
  264.           break ;
  265.         case 'e' :
  266.           if      (strcmp (optarg, "402040") == 0) 
  267.                   *function = R402040 ;
  268.           else if (strcmp (optarg, "WTA"   ) == 0)
  269.                   *function = WTA    ;
  270.           else error++ ; 
  271.           break ;
  272.         case 'r' :
  273.           *sel_cond = *sel_cond | RIGHT   ;
  274.           break ;
  275.         case 'w' :
  276.           *sel_cond = *sel_cond | WRONG   ;
  277.           break ;
  278.         case 'u' :
  279.           *sel_cond = *sel_cond | UNKNOWN ;
  280.           break ;
  281.         case 'a' :
  282.           *sel_cond = WRONG | RIGHT | UNKNOWN ;
  283.           break ;
  284.         case 'v' :
  285.           *output_text = ON ;
  286.           break ;
  287.         case 's' :
  288.           *statistics  = ON ;
  289.           break ;
  290.         case 'i' :
  291.           if ((in_file = fopen(optarg, "r")) == (FILE *) NULL)
  292.           {  
  293.              fprintf (stderr, "error:  can't read file %s \n", optarg) ;
  294.              error++ ;
  295.           } 
  296.           break ;
  297.         case 'o' :
  298.           if ((out_file = fopen(optarg, "w")) == (FILE *) NULL)
  299.           {  
  300.              fprintf (stderr, "error:  can't create file %s\n", optarg) ;
  301.              error++ ;
  302.           } 
  303.           break ;
  304.         default  : error++ ;
  305.       }
  306.  
  307.     if (*sel_cond == 0) *sel_cond = WRONG  ;
  308.  
  309.     if ((hl_flag & 1) == 0) 
  310.     {  switch (*function)
  311.        {
  312.          case R402040 : *low  = 0.4 ; break ;
  313.          case WTA     : *low  = 0.0 ; break ;
  314.        }
  315.     }
  316.  
  317.     if ((hl_flag & 2) == 0)
  318.     {  switch (*function)
  319.        {
  320.          case R402040 : *high = 0.6 ; break ;
  321.          case WTA     : *high = 0.0 ; break ;
  322.        }
  323.     }
  324.        
  325.     if (in_file  == (FILE *) NULL) in_file  = stdin  ;
  326.     if (out_file == (FILE *) NULL) out_file = stdout ;
  327.  
  328.     return (error) ;  
  329.   }
  330.  
  331.  
  332.  
  333. /*****************************************************************************/
  334. /* function read_file_header                                                 */
  335. /*                                                                           */
  336. /* reads from the input file :                                               */
  337. /*     no. of patterns                                                       */
  338. /*     no. of input units                                                    */
  339. /*     no. of output units                                                   */
  340. /*     startpattern                                                          */
  341. /*     endpattern                                                            */
  342. /*****************************************************************************/
  343.  
  344. int read_file_header (file_header_info)
  345.  
  346.   FileHeaderInfo  *file_header_info ;
  347.  
  348.   {
  349.     char  str1[80], str2[80], str3[80] ;
  350.     int   error ;
  351.  
  352.     error = 0 ;
  353.  
  354.     fscanf (in_file, "%s %s %s", str1, str2, str3) ;
  355.     if ((strcmp (str1, "SNNS"  ) != 0) ||   
  356.         (strcmp (str2, "result") != 0) ||  
  357.         (strcmp (str3, "file"  ) != 0))   error++ ;   
  358.       
  359.     if (error == 0)
  360.     {
  361.        fscanf (in_file, "%*s %*s %*s %*s %*s %*s %*s %*s") ;
  362.  
  363.        fscanf (in_file, "%*s %*s %*s %*s     %d", 
  364.            &(file_header_info -> no_of_patterns)    ) ;
  365.        fscanf (in_file, "%*s %*s %*s %*s %*s %d", 
  366.            &(file_header_info -> no_of_input_units) ) ;
  367.        fscanf (in_file, "%*s %*s %*s %*s %*s %d", 
  368.            &(file_header_info -> no_of_output_units)) ;
  369.        fscanf (in_file, "%*s %*s             %d", 
  370.            &(file_header_info -> startpattern      )) ;
  371.        fscanf (in_file, "%*s %*s             %d", 
  372.            &(file_header_info -> endpattern        )) ;
  373.           
  374.        file_header_info -> sub_pattern_present = 
  375.        (file_header_info -> endpattern) 
  376.        - (file_header_info -> startpattern)
  377.        + 1 
  378.            != (file_header_info -> no_of_patterns);
  379.        
  380.        fscanf (in_file, "%s", str1) ;
  381.  
  382.        if (strcmp (str1, "input") == 0)
  383.        {   
  384.          fscanf (in_file, "%s %s %s", str2, str3, str1) ;
  385.          if ((strcmp (str2, "patterns") == 0) &&  
  386.              (strcmp (str3, "included") == 0)) 
  387.               file_header_info -> input_pattern_included = 1 ;   
  388.          else file_header_info -> input_pattern_included = 0 ;
  389.        }
  390.        else file_header_info -> input_pattern_included = 0 ;
  391.  
  392.        if (strcmp (str1, "teaching") == 0) 
  393.        {
  394.          fscanf (in_file, "%s %s %s", str2, str3, str1) ; 
  395.          if ((strcmp (str2, "output"  ) == 0) &&  
  396.              (strcmp (str3, "included") == 0)) 
  397.               file_header_info -> teaching_output_included = 1 ;
  398.          else
  399.          {    file_header_info -> teaching_output_included = 0 ;
  400.               fprintf (stderr, "error:  missing teaching_output \n") ;
  401.               error++ ;
  402.          }   
  403.        }
  404.        else
  405.        {    file_header_info -> teaching_output_included = 0 ;
  406.             fprintf (stderr, "error:  missing teaching_output \n") ;
  407.             error++ ;
  408.        }   
  409.  
  410.      }
  411.      else 
  412.      {
  413.        fprintf (stderr, "error:  no SNNS result file\n") ;
  414.      }
  415.      return (error) ;
  416.   }
  417.  
  418.  
  419.  
  420. /*****************************************************************************/
  421. /* main program                                                              */
  422. /*****************************************************************************/
  423.  
  424. main (argc, argv)
  425.  
  426. int   argc   ;
  427. char  *argv[] ;
  428.  
  429. {
  430.   int             pat_no           ;
  431.   int             i, result        ;
  432.   int             function         ;
  433.   int             sel_cond         ;
  434.   int             output_text      ;
  435.   float           low, high        ;
  436.   int             statistics       ;
  437.   int             right, wrong, 
  438.                   unknown          ;
  439.   float           error            ;
  440.   float           *output          ;
  441.   float           *teaching_output ;
  442.   FileHeaderInfo  file_header_info ;
  443.  
  444.  
  445.   if (get_options (argc, argv, &function, &sel_cond, &output_text,
  446.                    &high, &low, &statistics) != 0)
  447.   {
  448.     fprintf (stderr, "usage: %s [options]        \n", argv[0]) ;
  449.     fprintf (stderr, "analyzes result files which are generated by SNNS\n");
  450.     fprintf (stderr, "options are:\n");
  451.     fprintf (stderr, 
  452.       "\t-w               : report wrong classified patterns (default)\n") ;
  453.     fprintf (stderr, 
  454.       "\t-r               : report right classified patterns\n") ;
  455.     fprintf (stderr, 
  456.       "\t-u               : report unclassified patterns\n") ;
  457.     fprintf (stderr, 
  458.       "\t-a               : same as -w -r -u\n") ;
  459.     fprintf (stderr, 
  460.       "\t-s               : show statistic information\n") ;
  461.     fprintf (stderr, 
  462.       "\t-v               : verbous mode\n");
  463.     fprintf (stderr, 
  464.       "\t-e <function>    : select error function \n") ;
  465.     fprintf (stderr, 
  466.       "\t                   <function> = [402040 | WTA]\n") ;
  467.     fprintf (stderr,
  468.       "\t                   default = 402040\n") ;
  469.     fprintf (stderr, 
  470.       "\t-l <float>       : lower bound level (see documentation) \n") ;
  471.     fprintf (stderr, 
  472.       "\t                   default: 0.4 for 402040\n") ;
  473.     fprintf (stderr, 
  474.       "\t                   default: 0.0 for WTA\n") ;
  475.     fprintf (stderr, 
  476.       "\t-h <float>       : upper bound level (see documentation) \n") ;
  477.     fprintf (stderr, 
  478.       "\t                   default: 0.6 for 402040\n") ;
  479.     fprintf (stderr, 
  480.       "\t                   default: 0.0 for WTA\n") ;
  481.     fprintf (stderr, 
  482.       "\t-i <input file>  : input result file (default stdin)\n");
  483.     fprintf (stderr, 
  484.       "\t-o <output file> : output file (default stdout)\n") ;
  485.   }
  486.   else
  487.   {
  488.     if (read_file_header (&file_header_info) == 0) 
  489.     {
  490.       output          = (float *) malloc (file_header_info.no_of_output_units 
  491.                       * sizeof(float)) ;
  492.       teaching_output = (float *) malloc (file_header_info.no_of_output_units 
  493.                       * sizeof(float)) ;
  494.  
  495.       wrong   = 0   ;
  496.       right   = 0   ;
  497.       unknown = 0   ;
  498.       error   = 0.0 ;
  499.  
  500.       for (pat_no = 0 ; pat_no < file_header_info.no_of_patterns ; pat_no++)
  501.       {                
  502.         if (file_header_info.input_pattern_included != 0)
  503.     { for (i = 1 ; i <= file_header_info.no_of_input_units ; i++)
  504.           fscanf (in_file, "%*f") ;
  505.         }
  506.  
  507.         for (i = 0 ; i < file_header_info.no_of_output_units ; i++)
  508.           fscanf (in_file, "%f", &teaching_output[i]) ;
  509.  
  510.         for (i = 0 ; i < file_header_info.no_of_output_units ; i++)
  511.           fscanf (in_file, "%f", &output[i]) ;
  512.         
  513.         switch (function)
  514.     { 
  515.           case R402040 :
  516.             result = F_402040 (output, teaching_output, 
  517.                    file_header_info.no_of_output_units, high, low);
  518.             break ;
  519.           case WTA    :
  520.             result = F_WTA    (output, teaching_output, 
  521.                    file_header_info.no_of_output_units, high, low);
  522.             break ;
  523.         }
  524.         
  525.         switch (result)
  526.     {
  527.       case WRONG   :  wrong++   ; break ;
  528.           case RIGHT   :  right++   ; break ;
  529.           case UNKNOWN :  unknown++ ; break ;
  530.     }
  531.  
  532.         if (statistics == OFF)
  533.         {     
  534.            if (output_text == OFF)
  535.       {
  536.              if      ((sel_cond & WRONG)   == result) 
  537.         fprintf(out_file, "%d\n", file_header_info.sub_pattern_present 
  538.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  539.              else if ((sel_cond & RIGHT)   == result) 
  540.         fprintf(out_file, "%d\n", file_header_info.sub_pattern_present
  541.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  542.              else if ((sel_cond & UNKNOWN) == result)
  543.         fprintf(out_file, "%d\n", file_header_info.sub_pattern_present 
  544.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  545.       }
  546.           else
  547.       {
  548.              if      ((sel_cond & WRONG)   == result) 
  549.         fprintf(out_file, "wrong   : %d\n", 
  550.             file_header_info.sub_pattern_present 
  551.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  552.              else if ((sel_cond & RIGHT)   == result) 
  553.         fprintf(out_file, "right   : %d\n", 
  554.             file_header_info.sub_pattern_present 
  555.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  556.              else if ((sel_cond & UNKNOWN) == result) 
  557.         fprintf(out_file, "unknown : %d\n", 
  558.             file_header_info.sub_pattern_present 
  559.             ? pat_no + 1 : pat_no + file_header_info.startpattern);
  560.       }
  561.         }
  562.         else error = error + Error (output, teaching_output, 
  563.                     file_header_info.no_of_output_units) ;
  564.     
  565.         if (pat_no < file_header_info.no_of_patterns - 1) 
  566.         fscanf (in_file, "%*s") ;    
  567.       }
  568.  
  569.       free (output)          ;
  570.       free (teaching_output) ;
  571.  
  572.       if (statistics == ON)
  573.       { 
  574.          fprintf (out_file, "STATISTICS ( %d patterns )\n", 
  575.           file_header_info.no_of_patterns) ;
  576.          fprintf (out_file, "wrong   : %5.2f %%  ( %d pattern(s) )\n", 
  577.                   100.0*wrong  /file_header_info.no_of_patterns, wrong) ;
  578.          fprintf (out_file, "right   : %5.2f %%  ( %d pattern(s) )\n",
  579.                   100.0*right  /file_header_info.no_of_patterns, right) ;
  580.          fprintf (out_file, "unknown : %5.2f %%  ( %d pattern(s) )\n",
  581.                   100.0*unknown/file_header_info.no_of_patterns, unknown) ;
  582.          fprintf (out_file, "error   : %f\n", error)  ;
  583.       } 
  584.     }
  585.     else
  586.     {
  587.       fprintf (stderr, "error:  invalid file header\n") ;
  588.     }
  589.   } 
  590.   if (in_file  != stdin)  fclose (in_file)  ;
  591.   if (out_file != stdout) fclose (out_file) ;
  592. }  
  593.  
  594.  
  595.  
  596. /*****************************************************************************/
  597. /* end of file                                                               */
  598. /*****************************************************************************/
  599.